#include "mini_chibicc.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

static void *xrealloc(void *p, size_t n) {
  void *q = realloc(p, n);
  if (!q) {
    fprintf(stderr, "realloc failed\n");
    exit(1);
  }
  return q;
}

void strarray_push(StringArray *a, char *s) {
  if (a->len + 1 > a->cap) {
    a->cap = a->cap ? a->cap * 2 : 8;
    a->data = (char **)xrealloc(a->data, (size_t)a->cap * sizeof(char *));
  }
  a->data[a->len++] = s;
}

char *format(const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
#if defined(_MSC_VER)
  va_list ap_copy;
  va_copy(ap_copy, ap);
  int n = _vscprintf(fmt, ap_copy);
  va_end(ap_copy);
  if (n < 0) {
    va_end(ap);
    return NULL;
  }
  char *buf = (char *)malloc((size_t)n + 1);
  if (!buf) {
    va_end(ap);
    return NULL;
  }
  vsnprintf(buf, (size_t)n + 1, fmt, ap);
#else
  va_list ap_copy;
  va_copy(ap_copy, ap);
  int n = vsnprintf(NULL, 0, fmt, ap_copy);
  va_end(ap_copy);
  if (n < 0) {
    va_end(ap);
    return NULL;
  }
  char *buf = (char *)malloc((size_t)n + 1);
  if (!buf) {
    va_end(ap);
    return NULL;
  }
  vsnprintf(buf, (size_t)n + 1, fmt, ap);
#endif
  va_end(ap);
  return buf;
}

void error(const char *fmt, ...) {
  fprintf(stderr, "error: ");
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  fputc('\n', stderr);
  exit(1);
}

char *basename(char *path) {
  if (!path) return path;
  char *p = path;
  char *last = path;
  while (*p) {
    if (*p == '/' || *p == '\\') {
      // 跳过连续分隔符
      char *q = p + 1;
      while (*q == '/' || *q == '\\') q++;
      if (*q) last = q;
      p = q;
      continue;
    }
    p++;
  }
  return last;
}